2

时间:2017年04月10日

说明:本文部分内容均摘取自书籍《Linux命令行与shell脚本编程大全》,版权归原作者所有。《Linux命令行与shell脚本编程大全》(第三版)第五章学习总结

第五章:理解shell

本章内容:

探究shell的类型
理解shell的父子关系
别出心裁的子shell用法
探究内建的shell命令

5.1 shell的类型

系统中启动什么样的shell程序取决于你个人的用户ID配置。在/etc/passwd文件中,在用户ID记录的第七个字段中列出了默认的shell程序。

默认的用户shell是bash shell,不过还有另外一个默认shell是/bin/sh,它作为默认的系统shell,用于那些需要启动时使用的系统shell脚本。

窍门:对bash shell脚本来说,这两种不同的shell(默认的交互shell和默认的系统shell)会造成问题。一定要阅读第十一章中有关bash shell脚本首行的语法要求,以避免这些麻烦。

5.2 shell的父子关系

通过输入命令bash,生成一个子shell。再执行其它命令时,会在子shell中执行。通过ps -f命令可以查看进程的父子关系,即子进程的PPID是父进程的PID。通过ps --forest命令,可以按层次查看进程。输入exit命令,退回子进程shell,回到父进程shell。exit还能用来登出当前的虚拟控制台终端。

base中可用的命令行参数:

-c string:从string中读取命令并进行处理
-i:启动一个能够接受用户输入的交互shell
-l:以登录shell的形式启动
-r:启动一个受限shell,用户会被限制在默认的目录中
-s:从标准输入中读取命令

5.2.1 进程列表

你可以在一行中指定要依次运行的一系列命令。通过分号(;)隔开即可。

通过使用中括号将命令列表变成进程列表。

命令列表:$ pwd ; ls ;cd /etc ; cd ; pwd ; ls
进程列表:$ (pwd ; ls ;cd /etc ; cd ; pwd ; ls)

要想知道是否生成了子shell,得借助一个使用了环境变量的命令。(环境变量会在第六章中详述。)这个命令就是echo $BASH_SUBSHELL。如果该命令返回0,就表明没有子shell。如果返回1或者其他更大的数字,就表明存在子shell。

5.2.2 别出心裁的子shell用法

在交互式的shell CLI中,还有很多更富有成效的子shell用法。进程列表、协程和管道(第十一章会讲到)都利用了子shell。在交互式shell中,一个搞笑的子shell用法就是使用了后台模式。

1.探索后台模式

在后台模式中运行命令可以在处理命令的同时让出CLI,以供他用。使用sleep命令来演示。sleep命令接受一个参数,该参数是你希望进程等待(睡眠)的秒数。
命令:sleep

命令演示:sleep 10
演示说明:将会话暂停10秒钟,然后返回shell CLI提示符。

要想将命令置入后台模式,可以在命令末尾加上字符&。当命令被置入后台,在shell CLI提示符返回之前,会出现两条信息。第一条在方括号中表示后台作业号;第二条表示后台作业的进程ID。

命令:jobs

命令格式:jobs -l
命令说明:显示后台作业信息。可以显示当前运行在后台模式中的所有用户的进程。

窍门:需要提醒的是:后台作业的结束状态可未必会一直等到合适的时候才现身。当作业结束状态突然出现在屏幕上的时候,你可别吃惊啊。

2.将进程列表置入后台

之前说过,进程列表是运行在子shell中的一条或多条命令。将进程列表置入后台模式会在命令输出上表现出些许不同。

命令演示:$ (sleep 2 ; echo $BASH_SUBSHELL ; sleep 2)&
演示说明:把进程列表置入后台模式。

把进程列表置入后台模式会产生一个作业号和进程ID,然后返回到提示符。 按一下回车键,得到另一个提示符。

3.协程

协程可以同时做两件事。它在后台生成一个子shell,并在这个shell中执行命令。
命令:coproc

命令格式:coproc 命令
命令说明:要在子shell中执行coproc命令。

协程会创建子shell执行命令,同时,将命令置入后台模式。使用jobs可以查看后台任务。

命令格式:coproc 任务名 { 命令 }
命令说明:为后台任务指定任务名并执行。

5.3 理解shell的內建命令

搞明白shell的內建命令和非內建(外部)命令非常重要。內建命令和非內建命令的操作方式大不相同。

5.3.1 外部命令

外部命令,有时候也被称为文件系统命令,是存在于bash shell之外的程序。它们并不是shell程序的一部分。外部程序通常位于/bin、/usr/bin、/sbin或/usr/sbin中。ps就是一个外部命令。你可以使用which和type命令找到它。

命令演示:swich ps
演示说明:查看ps命令程序所在路径。
命令演示:type -a ps
演示说明:查看ps命令程序所在路径。

当外部命令执行时,会创建出一个子进程。这种操作被称为衍生(forking)。作为外部命令,ps命令在执行时会创建出一个子进程。

5.3.2 內建命令

內建命令和外部命令的区别在于前者不需要使用子进程来执行。它们已经和shell编译成了一体,作为shell工具的组成部分。不需要借助外部程序文件来运行。

cd和exit命令都是內建与bash shell。

命令演示:type cd
演示说明:利用type命令来了解某个命令是否是內建的。

命令演示:type -a echo
演示说明:有些命令有多种实现。使用type命令的-a选项查看命令的不同实现。

命令演示:which pwd
演示说明:which命令只显示出了外部命令文件。

窍门:对于有多种实现的命令,如果想要使用其外部命令实现,直接指明对应的文件就可以了。例如,要使用外部命令pwd,可以输入/bin/pwd。

1.使用history命令

命令:history

命令格式:history
命令说明:查看最近用过的命令列表。通常历史记录会保存最近的1000条命令。

窍门:你可以设置保存在bash历史记录中的命令数。要想实现这一点,你需要修改名为HISTSIZE的环境变量(参见第六章)。

命令格式:history -a
命令说明:将命令历史记录写入.bash_history文件。

命令演示:!!
演示活门:执行上一条命令,即刚刚执行的命令。

命令演示:!20
演示说明:执行命令在历史列表中编号为20的命令。

2.命令别名

alias命令是另一个shell的內建命令。命令别名允许你为常用的命令(及其参数)创建另一个名称,从而将输入量减少到最低。

命令:alias

命令格式:alias -p
命令说明:查看当前可用的别名。

命令格式:alias li='ls -li'
命令说明:创建一个命令别名为li的命令,由ls -li组成。命令别名只在它被定义的shell进程中才有效。不过,可以使用环境变量,使得别名在不同的shell中都凑效。

5.4 小结

本章讨论了复杂的交互式程序:GNU bash shell。其中包括理解shell进程及其关系,如何生成子shell,以及子shell与父shell的关系。主要介绍了bash、exit、&、sleep、jobs、coproc、which、type、history、!、alias命令。

本章学习命令个人总结如下:

bash:创建一个子shell进程
exit:退出子shell进程,直到退出CLI客户端
&:将任务置入后台模式
sleep:将当前进程等待(休眠)
jobs:查看所有后台作业信息
coproc:创建一个子进程,并用子进程执行任务
which:查看命令程序所在文件路径(只显示外部命令文件)
type:查看命令程序所在文件路径(通过-a选项,显示每个命令的两种实现)
history:查看命令使用的历史记录(默认1000条,可修改HISTSIZE环境变量来控制显示条数)
!:执行命令历史记录里的命令(!!执行上一条命令,!n执行命令历史列表中编号为n的命令)
alias:为命令创建别名(默认只在被创建的shell进行中有效,可修改环境变量实现所有shell进程有效)

妙手空空
1.3k 声望370 粉丝

博观而约取,厚积而薄发